const nativeMethod = [
    {module: 'Zero_Device', method: 'getSystemInfo'},
    {module: 'Zero_Device', method: 'scan'},
    {module: 'Zero_Device', method: 'vibrate'},
    {module: 'Zero_Device', method: 'setKeepScreenOn'},
    {module: 'Zero_Device', method: 'getScreenBrightness'},
    {module: 'Zero_Device', method: 'setScreenBrightness'},
    {module: 'Zero_PageManager', method: 'closeWindow'},
    {module: 'Zero_PageManager', method: 'openWindow'},
    {module: 'Zero_Media', method: 'chooseImage'},
    {module: 'Zero_Media', method: 'previewImage'},
    {module: 'Zero_error', method: 'errorModule'},
    {module: 'Zero_Media', method: 'errorMethod'},
];

const z = {};
z.callbacks = {};
z.canIUse = function (methodName) {
    var use = false;
    nativeMethod.forEach(function (item) {
        if (methodName === item.method) {
            if (validateMethod(item)) {
                use = true;
            }
        }
    });
    return use;
};

nativeMethod.map(function (item) {
    z[item.method] = function (arg) {

        // if (!validateMethod(item)) {
        //     log('not support');
        //     if (arg && arg.fail) {
        //         arg.fail({
        //             message: 'not support'
        //         })
        //     }
        //     return;
        // }

        var nativeArg = {};
        for(var key in item){
            nativeArg[key] = item[key];
        }

        if (!arg) {
            invokeNative(item, nativeArg);
            return;
        }
        log('arg:' + JSON.stringify(arg));

        for (var key in arg) {
            nativeArg[key] = arg[key];
        }

        if (arg.success) {
            var successName = 's_' + uuid().replace(/-/g, '');
            this.callbacks[successName] = function (data) {
                var dataObj = data ? JSON.parse(data) : data;
                arg.success(dataObj);
                if (arg.complete) {
                    arg.complete({
                        code: 'success',
                        data: dataObj,
                    })
                }
                delete this.callbacks[successName]
            };
            nativeArg.success = 'z.callbacks.' + successName;
        }
        if (arg.fail) {
            var failName = 'f_' + uuid().replace(/-/g, '');
            this.callbacks[failName] = function (err) {
                var errObj = err ? JSON.parse(err) : err;
                arg.fail(errObj);
                if (arg.complete) {
                    arg.complete({
                        code: 'fail',
                        err: errObj,
                    })
                }
                delete this.callbacks[failName]
            };
            nativeArg.fail = 'z.callbacks.' + failName;
        }
        if (arg.complete) {
            delete nativeArg.complete;
        }

        log('nativeArg:' + JSON.stringify(nativeArg));
        invokeNative(item, nativeArg);
    }
});

console.log('z', z);

function invokeNative(item, arg) {
    // window[item.module][item.method](JSON.stringify(arg));
    log(JSON.stringify(arg));
    window.zero.call(JSON.stringify(arg));
}

function validateMethod(item) {
    // return window[item.module] && window[item.module][item.method]
    log(JSON.stringify(item));
    return window.zero.canIUse(JSON.stringify(item));
}

function log(message) {
    console.log('zero-js-bridge ' + message)
}

function uuid() {
    var s = [];
    var hexDigits = "0123456789abcdef";
    for (var i = 0; i < 36; i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
    }
    s[14] = "4";  // bits 12-15 of the time_hi_and_version field to 0010
    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);  // bits 6-7 of the clock_seq_hi_and_reserved to 01
    s[8] = s[13] = s[18] = s[23] = "-";

    var uuid = s.join("");
    return uuid;
}
